using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Terra.Core.Common.ApiResponse;
using Terra.Core.Common.ErrorCodes.Constants;
using Terra.Core.Common.Models.Pagination;
using Terra.Data.Models.Identity;
using Terra.Service.Identity.Interfaces;
using Terra.WebApi.Filters;

namespace Terra.WebApi.Areas.Admin.Controllers;

/// <summary>
/// 用户管理控制器
/// </summary>
/// <remarks>
/// 提供以下功能：
/// <list type="bullet">
/// <item><description>用户查询</description></item>
/// <item><description>用户详情</description></item>
/// <item><description>用户创建</description></item>
/// <item><description>用户更新</description></item>
/// <item><description>用户删除</description></item>
/// <item><description>用户密码管理</description></item>
/// <item><description>用户角色分配</description></item>
/// <item><description>用户状态管理</description></item>
/// </list>
/// </remarks>
[Area("Admin")]
[ApiController]
[Route("api/admin/users")]
[ApiExplorerSettings(GroupName = "v1-admin")]
[Authorize]
public class UserController : ControllerBase
{
    private readonly IUserService _userService;
    private readonly ILogger<UserController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="userService">用户服务</param>
    /// <param name="logger">日志记录器</param>
    public UserController(
        IUserService userService,
        ILogger<UserController> logger)
    {
        _userService = userService ?? throw new ArgumentNullException(nameof(userService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    #region 用户查询

    /// <summary>
    /// 分页查询用户
    /// </summary>
    /// <param name="query">查询条件</param>
    /// <returns>分页结果</returns>
    /// <response code="200">查询成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet]
    [ProducesResponseType(typeof(ApiResponse<PagedList<UserItemDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetUsers([FromQuery] UserQueryDto query)
    {
        var result = await _userService.GetPagedUsersAsync(query);
        return Ok(ApiResponse.Success(result));
    }

    /// <summary>
    /// 获取用户详情
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <returns>用户详情</returns>
    /// <response code="200">获取成功</response>
    /// <response code="404">用户不存在</response>
    /// <response code="401">未授权</response>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(ApiResponse<UserDetailDto>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetUserById(Guid id)
    {
        try
        {
            var result = await _userService.GetUserDetailAsync(id);
            return Ok(ApiResponse.Success(result));
        }
        catch (Exception ex) when (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
        {
            return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
        }
    }

    #endregion

    #region 用户创建和修改

    /// <summary>
    /// 创建用户
    /// </summary>
    /// <param name="dto">创建信息</param>
    /// <returns>创建结果</returns>
    /// <response code="201">创建成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="409">用户名/邮箱/手机号已存在</response>
    [HttpPost]
    [ProducesResponseType(typeof(ApiResponse<Guid>), 201)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 409)]
    public async Task<IActionResult> CreateUser([FromBody] UserCreateDto dto)
    {
        try
        {
            var userId = await _userService.CreateUserAsync(dto);
            return Created($"/api/admin/users/{userId}", ApiResponse.Success(userId));
        }
        catch (Exception ex)
        {
            // 用户名/邮箱/手机号已存在
            if (ex.Message.Contains(SecurityErrorCodes.USER_NAME_ALREADY_EXISTS) ||
                ex.Message.Contains(SecurityErrorCodes.USER_EMAIL_ALREADY_EXISTS) ||
                ex.Message.Contains(SecurityErrorCodes.USER_PHONE_ALREADY_EXISTS))
            {
                return Conflict(ApiResponse.Error(ex.Message));
            }

            // 密码不符合要求
            if (ex.Message.Contains(SecurityErrorCodes.USER_PASSWORD_INVALID))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.USER_PASSWORD_INVALID, "密码不符合复杂度要求"));
            }

            _logger.LogError(ex, "创建用户时出错");
            return BadRequest(ApiResponse.Error("创建用户失败"));
        }
    }

    /// <summary>
    /// 更新用户
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <param name="dto">更新信息</param>
    /// <returns>更新结果</returns>
    /// <response code="200">更新成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="404">用户不存在</response>
    /// <response code="409">邮箱/手机号已存在</response>
    /// <response code="403">系统用户不允许修改</response>
    [HttpPut("{id}")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 409)]
    public async Task<IActionResult> UpdateUser(Guid id, [FromBody] UserUpdateDto dto)
    {
        if (id != dto.Id)
        {
            return BadRequest(ApiResponse.Error("路径ID与请求体ID不匹配"));
        }

        try
        {
            var result = await _userService.UpdateUserAsync(dto);
            return Ok(ApiResponse.Success("用户更新成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.SYSTEM_USER_MODIFY_FORBIDDEN))
            {
                return Forbid();
            }

            if (ex.Message.Contains(SecurityErrorCodes.USER_EMAIL_ALREADY_EXISTS) ||
                ex.Message.Contains(SecurityErrorCodes.USER_PHONE_ALREADY_EXISTS))
            {
                return Conflict(ApiResponse.Error(ex.Message));
            }

            _logger.LogError(ex, "更新用户时出错");
            return BadRequest(ApiResponse.Error("更新用户失败"));
        }
    }

    /// <summary>
    /// 删除用户
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <returns>删除结果</returns>
    /// <response code="200">删除成功</response>
    /// <response code="401">未授权</response>
    /// <response code="403">系统用户不允许删除</response>
    /// <response code="404">用户不存在</response>
    [HttpDelete("{id}")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> DeleteUser(Guid id)
    {
        try
        {
            var result = await _userService.DeleteUserAsync(id);
            return Ok(ApiResponse.Success("用户删除成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.SYSTEM_USER_MODIFY_FORBIDDEN))
            {
                return Forbid();
            }

            _logger.LogError(ex, "删除用户时出错");
            return BadRequest(ApiResponse.Error("删除用户失败"));
        }
    }

    /// <summary>
    /// 批量删除用户
    /// </summary>
    /// <param name="ids">用户ID列表</param>
    /// <returns>删除结果</returns>
    /// <response code="200">删除成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpPost("batch-delete")]
    [ProducesResponseType(typeof(ApiResponse<int>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> BatchDeleteUsers([FromBody] List<Guid> ids)
    {
        if (ids == null || ids.Count == 0)
        {
            return BadRequest(ApiResponse.Error("用户ID列表不能为空"));
        }

        var count = await _userService.BatchDeleteUsersAsync(ids);
        return Ok(ApiResponse.Success(count, $"成功删除 {count} 个用户"));
    }

    #endregion

    #region 用户密码管理

    /// <summary>
    /// 重置用户密码
    /// </summary>
    /// <param name="dto">重置信息</param>
    /// <returns>重置结果</returns>
    /// <response code="200">重置成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="404">用户不存在</response>
    [HttpPost("reset-password")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto dto)
    {
        try
        {
            var result = await _userService.ResetPasswordAsync(dto);
            return Ok(ApiResponse.Success("密码重置成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.USER_PASSWORD_INVALID))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.USER_PASSWORD_INVALID, "密码不符合复杂度要求"));
            }

            _logger.LogError(ex, "重置用户密码时出错");
            return BadRequest(ApiResponse.Error("重置密码失败"));
        }
    }

    /// <summary>
    /// 修改用户密码
    /// </summary>
    /// <param name="dto">修改信息</param>
    /// <returns>修改结果</returns>
    /// <response code="200">修改成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="404">用户不存在</response>
    [HttpPost("change-password")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDto dto)
    {
        try
        {
            var result = await _userService.ChangePasswordAsync(dto);
            return Ok(ApiResponse.Success("密码修改成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.USER_PASSWORD_INVALID))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.USER_PASSWORD_INVALID, "密码不符合复杂度要求"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.InvalidCredentials))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.InvalidCredentials, "当前密码不正确"));
            }

            _logger.LogError(ex, "修改用户密码时出错");
            return BadRequest(ApiResponse.Error("修改密码失败"));
        }
    }

    #endregion

    #region 用户状态和角色管理

    /// <summary>
    /// 更新用户状态
    /// </summary>
    /// <param name="dto">状态信息</param>
    /// <returns>更新结果</returns>
    /// <response code="200">更新成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="403">系统用户不允许修改状态</response>
    /// <response code="404">用户不存在</response>
    [HttpPut("status")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> UpdateUserStatus([FromBody] UserStatusUpdateDto dto)
    {
        try
        {
            var result = await _userService.UpdateUserStatusAsync(dto);
            return Ok(ApiResponse.Success("用户状态更新成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.SYSTEM_USER_MODIFY_FORBIDDEN))
            {
                return Forbid();
            }

            if (ex.Message.Contains(SecurityErrorCodes.USER_STATUS_UPDATE_FAILED))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.USER_STATUS_UPDATE_FAILED, "用户状态更新失败"));
            }

            _logger.LogError(ex, "更新用户状态时出错");
            return BadRequest(ApiResponse.Error("更新用户状态失败"));
        }
    }

    /// <summary>
    /// 为用户分配角色
    /// </summary>
    /// <param name="dto">角色分配信息</param>
    /// <returns>分配结果</returns>
    /// <response code="200">分配成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="403">系统用户不允许修改角色</response>
    /// <response code="404">用户不存在</response>
    [HttpPut("roles")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> AssignRolesToUser([FromBody] UserRoleAssignDto dto)
    {
        try
        {
            var result = await _userService.AssignRolesToUserAsync(dto);
            return Ok(ApiResponse.Success("用户角色分配成功"));
        }
        catch (Exception ex)
        {
            if (ex.Message.Contains(SecurityErrorCodes.USER_NOT_FOUND))
            {
                return NotFound(ApiResponse.Error(SecurityErrorCodes.USER_NOT_FOUND, "用户不存在"));
            }

            if (ex.Message.Contains(SecurityErrorCodes.SYSTEM_USER_MODIFY_FORBIDDEN))
            {
                return Forbid();
            }

            if (ex.Message.Contains(SecurityErrorCodes.USER_ROLE_ASSIGN_FAILED))
            {
                return BadRequest(ApiResponse.Error(SecurityErrorCodes.USER_ROLE_ASSIGN_FAILED, "角色分配失败"));
            }

            if (ex.Message.Contains("角色不存在"))
            {
                return BadRequest(ApiResponse.Error("指定的某个角色不存在"));
            }

            _logger.LogError(ex, "分配用户角色时出错");
            return BadRequest(ApiResponse.Error("分配用户角色失败"));
        }
    }

    #endregion

    #region 数据验证

    /// <summary>
    /// 检查用户名是否存在
    /// </summary>
    /// <param name="userName">用户名</param>
    /// <param name="excludeUserId">排除的用户ID</param>
    /// <returns>检查结果</returns>
    /// <response code="200">检查成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet("check-username")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> CheckUserNameExists([FromQuery] string userName, [FromQuery] Guid? excludeUserId = null)
    {
        if (string.IsNullOrWhiteSpace(userName))
        {
            return BadRequest(ApiResponse.Error("用户名不能为空"));
        }

        var exists = await _userService.IsUserNameExistsAsync(userName, excludeUserId);
        return Ok(ApiResponse.Success(exists));
    }

    /// <summary>
    /// 检查邮箱是否存在
    /// </summary>
    /// <param name="email">邮箱</param>
    /// <param name="excludeUserId">排除的用户ID</param>
    /// <returns>检查结果</returns>
    /// <response code="200">检查成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet("check-email")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> CheckEmailExists([FromQuery] string email, [FromQuery] Guid? excludeUserId = null)
    {
        if (string.IsNullOrWhiteSpace(email))
        {
            return BadRequest(ApiResponse.Error("邮箱不能为空"));
        }

        var exists = await _userService.IsEmailExistsAsync(email, excludeUserId);
        return Ok(ApiResponse.Success(exists));
    }

    /// <summary>
    /// 检查手机号是否存在
    /// </summary>
    /// <param name="phoneNumber">手机号</param>
    /// <param name="excludeUserId">排除的用户ID</param>
    /// <returns>检查结果</returns>
    /// <response code="200">检查成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet("check-phone")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> CheckPhoneNumberExists([FromQuery] string phoneNumber, [FromQuery] Guid? excludeUserId = null)
    {
        if (string.IsNullOrWhiteSpace(phoneNumber))
        {
            return BadRequest(ApiResponse.Error("手机号不能为空"));
        }

        var exists = await _userService.IsPhoneNumberExistsAsync(phoneNumber, excludeUserId);
        return Ok(ApiResponse.Success(exists));
    }

    #endregion
}